package org.springframework.beans.factory.support;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.PropertyValue;
import org.springframework.core.AttributeAccessorSupport;

import java.util.ArrayList;
import java.util.List;

/**
 * @author:刘仁有
 * @desc:
 * @email:953506233@qq.com
 * @data:2019/12/14
 */
public abstract class AbstractBeanDefinition extends AttributeAccessorSupport implements BeanDefinition {

    public static final String SCOPE_DEFAULT = SCOPE_SINGLETON;

    public static final int AUTOWIRE_NO = BeanFactory.AUTOWIRE_NO;

    public static final int AUTOWIRE_BY_NAME = BeanFactory.AUTOWIRE_BY_NAME;

    public static final int AUTOWIRE_BY_TYPE = BeanFactory.AUTOWIRE_BY_TYPE;

    public static final int AUTOWIRE_CONSTRUCTOR = BeanFactory.AUTOWIRE_CONSTRUCTOR;

    private Class<?> beanClass;
    private String scope = SCOPE_SINGLETON;
    private boolean lazyInit = false;
    private String initMethodName;
    private List<PropertyValue> propertyValues;
    private int resolvedAutowireMode;
    private List<?> constructorArgumentValues;
    private List<PropertyValue> constructorArgumentPropertyValues;
    private boolean lenientConstructorResolution = true;
    private int role;
    private String factoryMethodName;
    private String factoryBeanName;

    public AbstractBeanDefinition() {}

    public AbstractBeanDefinition(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    @Override
    public Class<?> getBeanClass() {
        return beanClass;
    }

    @Override
    public void setBeanClass(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    @Override
    public String getScope() {
        return scope;
    }

    @Override
    public void setScope(String scope) {
        //单例不用改，scope是乱写的也不用改，只有用户传多例才改
        if(SCOPE_PROTOTYPE.equals(scope)){
            this.scope = scope;
        }
    }

    @Override
    public boolean isSingleton() {
        return SCOPE_SINGLETON.equals(scope);
    }

    @Override
    public boolean isPrototype() {
        return SCOPE_PROTOTYPE.equals(scope);
    }

    @Override
    public void setLazyInit(boolean lazyInit) {
        this.lazyInit = lazyInit;
    }

    @Override
    public boolean isLazyInit() {
        return lazyInit;
    }

    @Override
    public String getInitMethodName() {
        return initMethodName;
    }

    @Override
    public void setInitMethodName(String initMethodName) {
        this.initMethodName = initMethodName;
    }

    @Override
    public List<PropertyValue> getPropertyValues() {
        return propertyValues;
    }

    @Override
    public void setPropertyValues(List<PropertyValue> propertyValues) {
        this.propertyValues = propertyValues;
    }

    @Override
    public int getResolvedAutowireMode() {
        return resolvedAutowireMode;
    }

    @Override
    public void setResolvedAutowireMode(int autowireMode) {
        this.resolvedAutowireMode = autowireMode;
    }

    @Override
    public List<?> getConstructorArgumentValues() {
        return constructorArgumentValues;
    }

    @Override
    public boolean hasConstructorArgumentValues() {
        return constructorArgumentValues!=null&&!constructorArgumentValues.isEmpty();
    }

    @Override
    public List<PropertyValue> getConstructorArgumentPropertyValues() {
        return constructorArgumentPropertyValues;
    }

    @Override
    public void setConstructorArgumentPropertyValues(List<PropertyValue> constructorArgumentPropertyValues) {
        if(null==constructorArgumentPropertyValues||constructorArgumentPropertyValues.size()==0)return;
        this.constructorArgumentPropertyValues = constructorArgumentPropertyValues;
        List<Object> constructorArgumentValues = new ArrayList<>();
        for (PropertyValue pv:constructorArgumentPropertyValues) {
            constructorArgumentValues.add(pv.getValue());
        }
        this.constructorArgumentValues = constructorArgumentValues;
    }

    @Override
    public boolean isLenientConstructorResolution() {
        return lenientConstructorResolution;
    }

    @Override
    public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
        this.lenientConstructorResolution = lenientConstructorResolution;
    }

    @Override
    public void setRole(int role) {
        this.role = role;
    }

    @Override
    public int getRole() {
        return role;
    }

    @Override
    public String getFactoryMethodName() {
        return factoryMethodName;
    }

    @Override
    public void setFactoryMethodName(String factoryMethodName) {
        this.factoryMethodName = factoryMethodName;
    }

    @Override
    public String getFactoryBeanName() {
        return factoryBeanName;
    }

    @Override
    public void setFactoryBeanName(String factoryBeanName) {
        this.factoryBeanName = factoryBeanName;
    }
}

